package org.shangrila.bme.mb;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.model.SelectItem;
import javax.inject.Named;

import org.primefaces.event.RowEditEvent;
import org.shangrila.app.sys.cfg.AppInitInfo;
import org.shangrila.app.sys.shiro.SecUtil;
import org.shangrila.bme.eo.BmeContract;
import org.shangrila.bme.eo.BmeInvInfo;
import org.shangrila.bme.eo.BmePayroll;
import org.shangrila.bme.eo.BmeRtnInfo;
import org.shangrila.comm.dao.DbAccess;
import org.shangrila.comm.helper.IDHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

@Named
@SessionScoped
public class RtnInfoMB implements Serializable{

	private static final long serialVersionUID = -7323274807846820833L;
	
	private final Logger log = LoggerFactory.getLogger(this.getClass());
	
	private String operator="test";
	
	//获取相关数据字典
	private List<SelectItem> itemsRtnInfoStatus = AppInitInfo.getDropdownList("RtnInfoStatus");
	
	@Autowired
	private DbAccess db;
	
	/** io：当前的回款单*/
	private BmeRtnInfo io=new BmeRtnInfo();
	/** vod:请款单集合*/
	private List<BmePayroll> vod=new ArrayList<>();
	/** selected：已选择的请款单*/
	private BmeRtnInfo selected=new BmeRtnInfo();
	private List<BmePayroll> selectedVod=new ArrayList<>();
	
	/** selectedRtn：回款单详情*/
	private List<BmeRtnInfo> selectedRtn=new ArrayList<>();
	
	/** selectedContract：已选择的合同*/
	private BmeContract selectedContract=new BmeContract();
	/** bmeContracts：所有的合同集合*/
	private List<BmeContract> bmeContracts;
	
	
	
	public List<BmeRtnInfo> getSelectedRtn() {
		return selectedRtn;
	}
	public void setSelectedRtn(List<BmeRtnInfo> selectedRtn) {
		this.selectedRtn = selectedRtn;
	}
	public List<BmePayroll> getSelectedVod() {
		return selectedVod;
	}
	public void setSelectedVod(List<BmePayroll> selectedVod) {
		this.selectedVod = selectedVod;
	}
	
	public BmeContract getSelectedContract() {
		return selectedContract;
	}
	public void setSelectedContract(BmeContract selectedContract) {
		this.selectedContract = selectedContract;
	}
	public List<BmeContract> getBmeContracts() {
		return bmeContracts;
	}
	public void setBmeContracts(List<BmeContract> bmeContracts) {
		this.bmeContracts = bmeContracts;
	}
	public String getOperator() {
		return operator;
	}
	public void setOperator(String operator) {
		this.operator = operator;
	}
	public List<SelectItem> getItemsRtnInfoStatus() {
		return itemsRtnInfoStatus;
	}
	public void setItemsRtnInfoStatus(List<SelectItem> itemsRtnInfoStatus) {
		this.itemsRtnInfoStatus = itemsRtnInfoStatus;
	}
	public BmeRtnInfo getIo() {
		return io;
	}
	public void setIo(BmeRtnInfo io) {
		this.io = io;
	}
	public List<BmePayroll> getVod() {
		return vod;
	}
	public void setVod(List<BmePayroll> vod) {
		this.vod = vod;
	}
	public BmeRtnInfo getSelected() {
		return selected;
	}
	public void setSelected(BmeRtnInfo selected) {
		this.selected = selected;
	}
	
	@PostConstruct
	public void init() {
		
		log.info("@PostConstruct..."+this.getClass());
		newIo();
    	//查找bmeCustomerService实例初始化下拉数据
		BmeCommEntityService service = AppInitInfo.findMBeanByName("bmeCommEntityService",BmeCommEntityService.class);
    	bmeContracts = service.getBmeContracts();
    	selectedContract = bmeContracts.get(0);

		if(null!=selectedContract) {
			vod=selectedContract.getBmePayrolls();
	    	//vodIner=db.findAll(BmePayroll.class);
		}
		try{
			operator = SecUtil.getCachedShiroUser().getUserno();
		}
		catch(Exception ex){
			operator="bme";
		}
	}
		
	public void newIo(BmeRtnInfo bmeRtnInfo) {
		bmeRtnInfo.setId(IDHelper.genStrIDs(24));
		bmeRtnInfo.setRtnId(io.getRtnId());
		bmeRtnInfo.setAmount(io.getAmount());
		bmeRtnInfo.setRtnDate(io.getRtnDate());
		bmeRtnInfo.setStatus(io.getStatus());
		bmeRtnInfo.setBmeContract(selectedContract);
		bmeRtnInfo.setContName(selectedContract.getName());
		bmeRtnInfo.setCustName(selectedContract.getCustName());
		bmeRtnInfo.setCreateTime(new Date());
		bmeRtnInfo.setOperator(operator);
	}
	
	
	/**  
	 * <p>Title: saveAction</p>  
	 * <p>Description: 保存回款款单</p>  
	 * @return  
	 */
	public String saveAction() {
		
		//1、保存回款单
		if(selectedRtn.size()==0) {
			AppInitInfo.showMessage("回款单为空", "存在回款单详情才能保存");
		}else {
			
			db.beginTransaction();
			for (BmeRtnInfo rtnInfo : selectedRtn) {
				rtnInfo.setAmount(io.getAmount());
				rtnInfo.setStatus("2");
				db.insert(rtnInfo);
			}
			db.commitTransaction();
			AppInitInfo.showMessage("保存回款", "保存回款成功");
			
		}
		
		
		
		//2、判断该回款单所属的合同金额是否已经满足,改变合同的状态
		BigDecimal paySum = new BigDecimal("0");//同一合同的请款总数
		BmeContract contract = vod.get(0).getBmeContract();
		
		//查询同一合同的回款单集合
		StringBuilder csql=new StringBuilder("SELECT rt FROM BmeRtnInfo rt ");
		StringBuilder cwhere=new StringBuilder("WHERE rt.bmeContract=?1");
		csql.append(cwhere.toString());
		
		List<Object> params=new ArrayList<>();
		params.add(0,contract);
		List<BmeRtnInfo> bmeRtnInfos = db.findBySql(csql.toString(),params.toArray());
		
		//把改合同下的回款总额累加
		for (BmeRtnInfo rtn : bmeRtnInfos) {
			if (rtn.getPayAmount().compareTo(rtn.getRtnAmount())==0) {
				paySum=paySum.add(rtn.getRtnAmount());
			}
		}
		
		//如果合同金额等于合同下回款集合的已回款总数，合同状态改为3
		if(contract.getPrice().compareTo(paySum)==0) {
			db.beginTransaction();
			contract.setStatus("4");
			db.update(contract);
			db.commitTransaction();
		}
		return null;
	}
	
	public void newIo() {
    	io = new BmeRtnInfo();
    	io.setId(IDHelper.genStrID(24));
    	io.setRtnId(IDHelper.genStrIDs(24));
    	io.setStatus("1");
    	selectedContract=null;
    	vod=null;
    	selected=null; 
    }
	
	public String commitAction() {
		
		newIo();
		return null;
	}
	
	//选择合同
	public void onSelectedContract() {
			
		selectedRtn.clear();	
		if(null!=selectedContract) {
			vod=selectedContract.getBmePayrolls();			
		}
			
	}
	
	
	/**  
	 * <p>Title: savePayroll</p>  
	 * <p>Description: 选择请款单,同时提出重复的请款单</p>  
	 * @return  
	 */
	public String selectPayroll() {
		
		//1、已选中的情况单集合查重
		for (int j=0;j<selectedVod.size();j++) {
			
			BmeRtnInfo bmeRtnInfo = new BmeRtnInfo();
			
			//第一次选择汇款单
			if(selectedRtn.size()==0) {
				newIo(bmeRtnInfo);
				bmeRtnInfo.setBmePayroll(selectedVod.get(j));
				bmeRtnInfo.setPayAmount(selectedVod.get(j).getAmount());
				selectedRtn.add(bmeRtnInfo);
			}else {
				//多次选择汇款单，需要去重
				for(int i=0;i<selectedRtn.size();i++) {
					
					if(selectedVod.contains(selectedRtn.get(i).getBmePayroll())) {
						selectedVod.remove(selectedRtn.get(i).getBmePayroll());
					}
				}
				//去重后存在的请款单，放入到集合中
				if(selectedVod.size()>0) {
					for (BmePayroll bmePayroll : selectedVod) {
						newIo(bmeRtnInfo);
						bmeRtnInfo.setBmePayroll(bmePayroll);
						bmeRtnInfo.setPayAmount(bmePayroll.getAmount());
						selectedRtn.add(bmeRtnInfo);
					}
				}
			}
			
		}
		
		//判断已选中的汇款单，通过合同编号、请款单号，在数据库中是否有对应的回款记录
		StringBuilder sql=new StringBuilder("SELECT rt FROM BmeRtnInfo rt ");
		StringBuilder where=new StringBuilder("WHERE rt.bmeContract=?1 AND rt.bmePayroll=?2");
		sql.append(where.toString());
		List<Object> params=new ArrayList<>();
		for (BmeRtnInfo bmeRtnInfo : selectedRtn) {
			params.add(0, bmeRtnInfo.getBmeContract());
			params.add(1, bmeRtnInfo.getBmePayroll());
			List<BmeRtnInfo> bmeRtnInfos = db.findBySql(sql.toString(),params.toArray());
			
			//根据该请款单是否有请款记录进行相应处理
			if(bmeRtnInfos.isEmpty()) {
				bmeRtnInfo.setRtnAmount(new BigDecimal("0"));
				bmeRtnInfo.setAsnAmount(new BigDecimal("0"));
				bmeRtnInfo.setRtnPercent("0.00%");
			}else {
				
				List<BigDecimal> maxs=new ArrayList<BigDecimal>();
				BigDecimal sum=new BigDecimal("0");//已回款
				BigDecimal nosum=new BigDecimal("0");//未回款
				for (BmeRtnInfo rtn : bmeRtnInfos) {
					maxs.add(rtn.getRtnAmount());
				}
				sum=Collections.max(maxs);
				nosum=bmeRtnInfo.getPayAmount().subtract(sum);
				BigDecimal divide = sum.divide(bmeRtnInfo.getPayAmount(),2,BigDecimal.ROUND_HALF_UP);
				NumberFormat instance = NumberFormat.getPercentInstance();
				instance.setMaximumFractionDigits(2);
				bmeRtnInfo.setRtnAmount(sum);
				bmeRtnInfo.setAsnAmount(nosum);
				bmeRtnInfo.setRtnPercent(instance.format(divide.doubleValue()));
			}
		}
		return null;
	}
	
	/**  
	 * <p>Title: delPayroll</p>  
	 * <p>Description: 删除回款单详情</p>  
	 * @return  
	 */
	public String delPayroll() {
		 
		selectedRtn.remove(selected);
		AppInitInfo.showMessage("记录删除", "处理成功");
		return null;
	}
	
	/**  
	 * <p>Title: onRowEdit</p>  
	 * <p>Description: 编辑回款单详细信息</p>  
	 * @param event  
	 */
	public void onRowEdit(RowEditEvent event) {
		
		selected=selectedRtn.get(selectedRtn.indexOf((BmeRtnInfo)event.getObject()));//获取行编
		List<BigDecimal> maxs=new ArrayList<BigDecimal>();
		BigDecimal sum = new BigDecimal("0");//回款金额累计
		
		//1、查询该请款单在数据库中的请款集合，获取请款总额
		StringBuilder sql=new StringBuilder("SELECT rt FROM BmeRtnInfo rt ");
		StringBuilder where=new StringBuilder("WHERE rt.bmeContract=?1 AND rt.bmePayroll=?2");
		sql.append(where.toString());
		List<Object> params=new ArrayList<>();
		
		params.add(0, selected.getBmeContract());
		params.add(1, selected.getBmePayroll());
		db.begin();
		for (@SuppressWarnings("unused") BmeRtnInfo bmeRtnInfo : selectedRtn) {
			List<BmeRtnInfo> bmeRtnInfos = db.findBySql(sql.toString(),params.toArray());
			if(!bmeRtnInfos.isEmpty()) {
				for (BmeRtnInfo rtn : bmeRtnInfos) {
					maxs.add(rtn.getRtnAmount());
				}
			}else {
				maxs.add(new BigDecimal("0"));
			}
		}
		db.commit();
		
		//2、判断回款金额是否大于请款金额
		BigDecimal rtnAmount = selected.getRtnAmount();
		BigDecimal payAmount = selected.getPayAmount();
		if(rtnAmount.compareTo(payAmount)==1) {
			AppInitInfo.showMessage("输入金额错误", "已回款金额不能大于请款金额");
		}else {
			//计算回款金额
			BigDecimal max = Collections.max(maxs);
			if(payAmount.compareTo(Collections.max(maxs))==0||payAmount.compareTo(Collections.max(maxs))==-1) {
				AppInitInfo.showMessage("消息提醒", "该请款单回款已经完成");
				return;
			}else {
				if (max.compareTo(rtnAmount)==1||max.compareTo(rtnAmount)==0) {
					AppInitInfo.showMessage("已回款有误", "已回款数为："+max);
					return;
				}else {
					
					sum=sum.add(rtnAmount.subtract(Collections.max(maxs)));
					io.setAmount(sum);
				}
			}
			
			//重置回款比例
			BigDecimal divide = rtnAmount.divide(payAmount,2,BigDecimal.ROUND_HALF_UP);
			NumberFormat percent = NumberFormat.getPercentInstance();
			percent.setMaximumFractionDigits(2);
			
			selected.setAsnAmount(selected.getPayAmount().subtract(selected.getRtnAmount()));
			selected.setRtnPercent(percent.format(divide));
		}
		
		
		AppInitInfo.showMessage("请款信息", "修改成功");
		
	}
	
	/**  
	 * <p>Title: onRowCancel</p>  
	 * <p>Description: 取消回款单行编辑</p>  
	 * @param event  
	 */
	public void onRowCancel(RowEditEvent event) {
		AppInitInfo.showMessage("取消修改", "处理成功");
	}
	
}
